package Options::Attributes::API::InterfacePlaceWebOrder;

use Options::Attributes::API::WebServiceLink;
our @ISA = qw(Options::Attributes::API::WebServiceLink)
    ;    # inherits from WebServiceLink

sub new {
    my ($class) = @_;

    # Call the constructor of the parent class.
    my $self = $class->SUPER::new( $_[1], $_[2], $_[3], $_[4] );
    bless $self, $class;
    return $self;
}

sub _setupParams {
    my $self      = shift;
    my $dataTypes = {
        'TitleCode'              => 'string',
        'Salutation'             => 'string',
        'FirstName'              => 'string',
        'Surname'                => 'string',
        'Address1'               => 'string',
        'Address2'               => 'string',
        'Address3'               => 'string',
        'Town'                   => 'string',
        'County'                 => 'string',
        'Country'                => 'string',
        'Postcode'               => 'string',
        'PostcodeStrip'          => 'string',
        'DayPhone'               => 'string',
        'Fax'                    => 'string',
        'Type'                   => 'string',
        'AddressRef1'            => 'string',
        'AddressRef2'            => 'string',
        'EveningPhone'           => 'string',
        'Email'                  => 'string',
        'Email2'                 => 'string',
        'JobTitle'               => 'string',
        'MobilePhone'            => 'string',
        'TradeCustomer'          => 'boolean',
        'AccountBalance'         => 'decimal',
        'AccountBalanceCurr'     => 'decimal',
        'InvoiceAccount'         => 'boolean',
        'ShopperID'              => 'string',
        'AlternativeReference'   => 'string',
        'ShopCustomer'           => 'boolean',
        'ShipCompletePreference' => 'boolean',
        'VatReceiptRequired'     => 'boolean',
        'VatRefundRequired'      => 'boolean',
        'RentOptOut'             => 'boolean',
        'MailOptOut'             => 'boolean',
        'AllowSubstitutes'       => 'boolean',
        'EmailPromotionFlag'     => 'boolean',
        'EmailRentFlag'          => 'boolean',
        'FaxPromotionFlag'       => 'boolean',
        'FaxRentFlag'            => 'boolean',
        'PhonePromotionFlag'     => 'boolean',
        'PhoneRentFlag'          => 'boolean',
        'EmailOptOut'            => 'boolean',
        'LastMailingCode'        => 'string',
        'Modified'               => 'boolean',
        'ModifiedOn'             => 'dateTime',
        'AddressNumber'          => 'int',
        'Comments'               => 'string',

        'StatusCode'                => 'string',
        'CalculateShipping'         => 'boolean',
        'CardAmount'                => 'decimal',
        'CashAmount'                => 'decimal',
        'CatalogueRequest'          => 'boolean',
        'CatalogueRequestSourceKey' => 'string',
        'ChequeAmount'              => 'decimal',
        'CreditAmount'              => 'decimal',
        'CountryCode'               => 'string',
        'CustomerNumber'            => 'int',
        'Currency'                  => 'string',
        'CustomerType'              => 'string',
        'Despatched'                => 'boolean',
        'DeliverDate'               => 'dateTime',
        'Discount'                  => 'decimal',
        'OrderDate'                 => 'dateTime',
        'OrderNumber'               => 'string',
        'OrderType'                 => 'string',
        'PaidFor'                   => 'boolean',
        'PrimaryPaymentMethod'      => 'string',
        'SalesNumber'               => 'string',
        'Reprice'                   => 'boolean',
        'ShipComplete'              => 'boolean',
        'ShippingMethod'            => 'string',
        'ShippingCost'              => 'decimal',
        'ShopNumber'                => 'int',
        'SourceKey'                 => 'string',
        'TaxRefund'                 => 'boolean',
        'TillNumber'                => 'int',
        'VoucherAmount'             => 'decimal',
        'Warehouse'                 => 'string',
        'CCType'                    => 'string',
        'CCNumber'                  => 'string',
        'CCCv2'                     => 'string',
        'CCExpiryMonth'             => 'int',
        'CCExpiryYear'              => 'int',
        'CCIssueNumber'             => 'int',
        'CCStartMonth'              => 'int',
        'CCStartYear'               => 'int',
        'CCAuthCode'                => 'string',
        'CCTransactionCode'         => 'string',
        'CCReceiptNumber'           => 'string',
        'EnteredBy'                 => 'string',
        'ProductCode'               => 'string',
        'Quantity'                  => 'int',
        'Price'                     => 'decimal',
        'ManualPrice'               => 'boolean',
        'Description'               => 'string',
        'IsPromotion'               => 'boolean',
        'PricePer'                  => 'int',
        'SourceKey'                 => 'string',
        'CCChargeCode'              => 'string',
        'CCDescription'             => 'string',
        'CCUnitCharge'              => 'decimal',
        'GCChargeCode'              => 'string',
        'GCDescription'             => 'string',
        'GCUnitCharge'              => 'decimal',
        'TextType' => 'tns:TextTypeType',    # Internal - option - investigate
        'Comment'  => 'string',
        'UserDefined1' => 'string',
        'UserDefined2' => 'string',
        'UserDefined3' => 'string',
    };

    my @CreditCard
        = qw(CCType CCNumber CCCv2 CCExpiryMonth CCExpiryYear CCIssueNumber CCStartMonth CCStartYear CCAuthCode CCTransactionCode CCReceiptNumber);
    my @OrderHeader
        = qw(CalculateShipping CardAmount CashAmount CatalogueRequest CatalogueRequestSourceKey ChequeAmount CreditAmount CountryCode CustomerNumber ShopperID Currency CustomerType Despatched DeliverDate Discount OrderDate OrderNumber OrderType PaidFor PrimaryPaymentMethod SalesNumber Reprice ShipComplete ShippingMethod ShippingCost SourceKey TaxRefund VoucherAmount Warehouse EnteredBy);

    my @CustomerUserDefined = qw(UserDefined1 UserDefined2 UserDefined3);

    my @CustomerAdditionalAddressLines
        = qw(AddressNumber StatusCode TitleCode Salutation FirstName Surname Type Address1 Address2 Address3 Town County Country Postcode PostcodeStrip DayPhone Fax Comments AddressRef1 AddressRef2 EveningPhone Email JobTitle MobilePhone ModifiedOn );

    # TillNumber ShopNumber
    my @OrderLine
        = qw(ProductCode Quantity Price ManualPrice Description IsPromotion PricePer SourceKey );

    my @CustomerHeaderFields
        = qw(CustomerNumber StatusCode TitleCode Salutation FirstName Surname Address1 Address2 Address3 Town County Country Postcode PostcodeStrip DayPhone Fax Type AddressRef1 AddressRef2 EveningPhone Email Email2 JobTitle MobilePhone TradeCustomer CreditAmount AccountBalance AccountBalanceCurr InvoiceAccount ShopperID AlternativeReference ShopCustomer ShipCompletePreference VatReceiptRequired VatRefundRequired RentOptOut MailOptOut AllowSubstitutes EmailPromotionFlag EmailRentFlag FaxPromotionFlag FaxRentFlag PhonePromotionFlag PhoneRentFlag EmailOptOut LastMailingCode Modified ModifiedOn );

    #   CustomisationCharges GeneralCharges Comments
    my @CCOrderCharge = qw(CCChargeCode CCDescription CCUnitCharge);
    my @GCOrderCharge = qw(GCChargeCode GCDescription GCUnitCharge);
    my @OrderText     = qw(TextType Comment);
    my @SalesOrder    = qw(OrderHeader OrderLines );

    # CustomisationCharges GeneralCharges Comments
    my @Comments             = qw(OrderText);
    my @GeneralCharges       = qw(OrderCharge);
    my @CustomisationCharges = qw(OrderCharge);

    my $envelopeElement;
    my @partOrderHeader           = ();
    my @partCreditCard            = ();
    my @partOrderLine             = ();
    my @partOrderLines            = ();
    my @partCCOrderCharge         = ();
    my @partGCOrderCharge         = ();
    my @partOrderCharges1         = ();
    my @partOrderCharges2         = ();
    my @partSalesOrder            = ();
    my @partOrderText             = ();
    my @partOrderTexts            = ();
    my @CustomerAdditionalAddress = ();
    my @CustomerHeader            = ();
    my @partCustomerUserDefined   = ();

    foreach (@CreditCard) {
        $envelopeElement = SOAP::Data->type( $dataTypes->{$_} )
            ->name( $_ => $self->{_WSRequest}->{$_} );
        push( @partCreditCard, $envelopeElement );
    }

    foreach (@OrderHeader) {
        $envelopeElement = SOAP::Data->type( $dataTypes->{$_} )
            ->name( $_ => $self->{_WSRequest}->{$_} );
        push( @partOrderHeader, $envelopeElement );
    }

    foreach (@CustomerUserDefined) {
        $envelopeElement = SOAP::Data->type( $dataTypes->{$_} )
            ->name( $_ => $self->{_WSRequest}->{$_} );
        push( @partCustomerUserDefined, $envelopeElement );
    }

    foreach (@CustomerAdditionalAddressLines) {
        $envelopeElement = SOAP::Data->type( $dataTypes->{$_} )
            ->name( $_ => getAA( $self->{_WSRequest}, $_ ) );
        push( @CustomerAdditionalAddress, $envelopeElement );
    }

    foreach (@CustomerHeaderFields) {
        $envelopeElement = SOAP::Data->type( $dataTypes->{$_} )
            ->name( $_ => $self->{_WSRequest}->{$_} );
        push( @CustomerHeader, $envelopeElement );
    }

    #START DO THIS FOR EACH ORDER LINE
    foreach $OrderItem ( @{ $self->{_WSRequest}->{OrderLine} } ) {
        foreach (@OrderLine) {
            $envelopeElement = SOAP::Data->type( $dataTypes->{$_} )
                ->name( $_ => $OrderItem->{$_} );
            push( @partOrderLine, $envelopeElement );
        }
        $envelopeElement = SOAP::Data->name(
            'OrderLine' => \SOAP::Data->value(@partOrderLine) );
        push( @partOrderLines, $envelopeElement );
        @partOrderLine = ();

        foreach (@CCOrderCharge) {
            $envelopeElement = SOAP::Data->type( $dataTypes{$_} )
                ->name( substr( $_, 2 ) => $OrderItem->{$_} );
            push( @partOrderCharge, $envelopeElement );
        }
        $envelopeElement = SOAP::Data->name(
            'OrderCharge' => \SOAP::Data->value(@partOrderCharge) );
        push( @partOrderCharges1, $envelopeElement );
        @partOrderCharge = ();

        foreach (@GCOrderCharge) {
            $envelopeElement = SOAP::Data->type( $dataTypes{$_} )
                ->name( substr( $_, 2 ) => $OrderItem->{$_} );
            push( @partOrderCharge, $envelopeElement );
        }
        $envelopeElement = SOAP::Data->name(
            'OrderCharge' => \SOAP::Data->value(@partOrderCharge) );
        push( @partOrderCharges2, $envelopeElement );
        @partOrderCharge = ();

        foreach (@OrderText) {
            $envelopeElement = SOAP::Data->type( $dataTypes->{$_} )
                ->name( $_ => $OrderItem->{$_} );
            push( @partOrderText, $envelopeElement );
        }
        $envelopeElement = SOAP::Data->name(
            'OrderText' => \SOAP::Data->value(@partOrderText) );
        push( @partOrderTexts, $envelopeElement );
        @partOrderText = ();
    }

    #STOP DO THIS FOR EACH ORDER LINE

    #PUT ALL THE STUFF TOGETHER
    my @params = SOAP::Data->name(
        'Customer' => \SOAP::Data->value(
            @CustomerHeader,
            SOAP::Data->name(
                'AdditionalAddresses' => \SOAP::Data->value(
                    SOAP::Data->name(
                        'CustomerAdditionalAddress' =>
                            \SOAP::Data->value(@CustomerAdditionalAddress)
                    )
                )
            ),
            SOAP::Data->name(
                'CustomerUserDefined' =>
                    \SOAP::Data->value(@partCustomerUserDefined)
            )
        ),
        SOAP::Data->name(
            'NewOrder' => \SOAP::Data->value(
                SOAP::Data->name(
                    'OrderHeader' => \SOAP::Data->value(
                        @partOrderHeader,
                        SOAP::Data->name(
                            'CreditCard' =>
                                \SOAP::Data->value(@partCreditCard)
                        )
                    )
                ),
                SOAP::Data->name(
                    'OrderLines' => \SOAP::Data->value(@partOrderLines)
                )
            ),
        )
    );
    return @params;
}

sub getAA {
    my ( $hashref, $valueToExtract ) = @_;
    return $hashref->{ 'AA_' . $valueToExtract };
}

1;
